package com.example.mysharding.test;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class CompletableFutureExample {

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        Executor executor = Executors.newFixedThreadPool(10);
        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
            //do something
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "aaa";
        }, executor).thenAccept((s) -> System.out.println(s + " world"));


//        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> "Hello")
//                .thenRun(() -> System.out.println("do other things. 比如异步打印日志或发送消息"));
//
//        //如果只想在一个CompletableFuture任务执行完后，进行一些后续的处理，不需要返回值，那么可以用thenRun回调方法来完成。
//        //如果主线程不依赖thenRun中的代码执行完成，也不需要使用get()方法阻塞主线程。//输出：Hello world
//        CompletableFuture<Void> future2 = CompletableFuture.supplyAsync(() -> "Hello")
//                .thenAccept((s) -> System.out.println(s + " world"));
////
////        //回调方法希望使用异步任务的结果，并不需要返回值，那么可以使用thenAccept方法
//        CompletableFuture<Boolean> future3 = CompletableFuture.supplyAsync(() -> {
//            return fetchPrice();
//        }).thenApply((s) -> isMainPoi(s));   // boolean isMainPoi(int poiId);

        future.get();
//
//        //希望将异步任务的结果做进一步处理，并需要返回值，则使用thenApply方法。
//        //如果主线程要获取回调方法的返回，还是要用get()方法阻塞得到,创建异步执行任务:
//        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(CompletableFutureExample::fetchPrice);
//
//        // 如果执行成功:
//        cf.thenAccept((result) -> {
//            System.out.println("price: " + result);
//        });
//        // 如果执行异常:
//        cf.exceptionally((e) -> {
//            e.printStackTrace();
//            return null;
//        });

        // 主线程不要立刻结束，否则CompletableFuture默认使用的线程池会立刻关闭:
        Thread.sleep(200);
    }

    static Double fetchPrice() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        if (Math.random() < 0.3) {
            throw new RuntimeException("fetch price failed!");
        }
        return 5 + Math.random() * 20;
    }
}